package com.petRescueCenter.demo.user.controller;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.petRescueCenter.demo.common.enumPackage.LockedEmun;
import com.petRescueCenter.demo.common.enumPackage.TypeEmun;
import com.petRescueCenter.demo.common.util.MD5Util;
import com.petRescueCenter.demo.common.util.ProjectPath;
import com.petRescueCenter.demo.common.web.VueResponse;
import com.petRescueCenter.demo.common.web.VuejsPageRequest;
import com.petRescueCenter.demo.user.entity.User;
import com.petRescueCenter.demo.user.entity.dto.UserChangeDTO;
import com.petRescueCenter.demo.user.entity.dto.UserDTO;
import com.petRescueCenter.demo.user.entity.dto.UserQueryDTO;
import com.petRescueCenter.demo.user.service.IUserService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(description = "用戶相关的api")
@RestController
@RequestMapping(value = "/user")
public class UserController {
	@Autowired
	private IUserService userService;
	@Autowired
	DefaultKaptcha defaultKaptcha;

	@ApiOperation(value = "查询用户信息", notes = "分页返回")
	@GetMapping
	public Page<UserDTO> getAll(UserQueryDTO userQueryDTO, VuejsPageRequest pageRequest) {
		return userService.findAll(UserQueryDTO.getWhereClause(userQueryDTO), pageRequest.getPageable());
	}

	@ApiOperation(value = "用户注册")
	@PostMapping("/register")
	public VueResponse register(@RequestParam("name") String name, @RequestParam("password") String password,
			@RequestParam("vrifyCode") String vrifyCode, HttpSession session, HttpServletRequest request) {
		try {
			String captchaId = (String) request.getSession().getAttribute("vrifyCode");

			if (!captchaId.equals(vrifyCode)) {
				return new VueResponse(false, "验证码错误！");
			} else {
				User user = new User();
				if (!userService.existsByName(name)) {
					user.setName(name);
					// 加盐加密
					user.setPassword(MD5Util.encode(password));
					user.setType(TypeEmun.ORDINARY);
					user.setLocked(LockedEmun.NO);
					user.setImg("img/user/user-default.png");
					userService.save(user);
					Map<String, Object> map = new HashMap<String, Object>();
					User userSession = new User();
					userSession.setName(name);

					userSession.setId(user.getId());
					userSession.setType(user.getType());
					map.put("userSession", userSession);
					map.put("msg", "注册成功!");
					return new VueResponse(true, map);
				} else {
					return new VueResponse(false, "该用户昵称已存在！");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new VueResponse(false, "注册失败！");

		}
	}

	@ApiOperation(value = "用户登录")
	@PostMapping("/login")
	public VueResponse login(@RequestParam("name") String name, @RequestParam("password") String password,
			@RequestParam("vrifyCode") String vrifyCode, HttpServletRequest request) {
		try {
			String captchaId = (String) request.getSession().getAttribute("vrifyCode");
			HttpSession session = request.getSession();
			if (!captchaId.equals(vrifyCode)) {
				return new VueResponse(false, "验证码错误！");
			} else {
				if (userService.existsByName(name)) {
					User user = new User();
					user = userService.findByName(name);
					if (user.getLocked().equals(LockedEmun.NO)) {
						if (user.getPassword().equals(MD5Util.encode(password))) {
							User userSession = new User();
							userSession.setName(name);
							userSession.setId(user.getId());
							userSession.setType(user.getType());
							session.setAttribute("userSession", userSession);
							Map<String, Object> map = new HashMap<String, Object>();
							map.put("userSession", userSession);
							map.put("msg", "登录成功!");

							return new VueResponse(true, map);
						} else {
							return new VueResponse(false, "密码错误！");
						}
					} else {
						return new VueResponse(false, "该用户已被禁用！");
					}
				}
				return new VueResponse(true, "该用户不存在！");
			}
		} catch (Exception e) {
			e.printStackTrace();

			return new VueResponse(false, "登录失败！");
		}
	}

	@ApiOperation(value = "获取验证码")
	@GetMapping("/createImageCode")
	public void createImageCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
		byte[] captchaChallengeAsJpeg = null;
		ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
		try {
			// 生产验证码字符串并保存到session中
			String createText = defaultKaptcha.createText();
			request.getSession().setAttribute("vrifyCode", createText);
			// 使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
			BufferedImage challenge = defaultKaptcha.createImage(createText);
			ImageIO.write(challenge, "jpg", jpegOutputStream);
		} catch (IllegalArgumentException e) {
			response.sendError(HttpServletResponse.SC_NOT_FOUND);
			return;
		}

		// 定义response输出类型为image/jpeg类型，使用response输出流输出图片的byte数组
		captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
		response.setHeader("Cache-Control", "no-store");
		response.setHeader("Pragma", "no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/jpeg");
		ServletOutputStream responseOutputStream = response.getOutputStream();
		responseOutputStream.write(captchaChallengeAsJpeg);
		responseOutputStream.flush();
		responseOutputStream.close();
	}

	@ApiOperation(value = "用户改密码")
	@PostMapping
	public VueResponse changePassword(@RequestParam("oldPassword") String oldPassword,
			@RequestParam("newPassword") String newPassword, HttpSession session) {

		try {
			User userSession = (User) session.getAttribute("userSession");
			if (userSession == null) {
				return new VueResponse(false, "用户非法登录！");
			}
			User user = userService.findById(userSession.getId());
			if (user.getPassword().equals(MD5Util.encode(oldPassword))) {
				user.setPassword(MD5Util.encode(newPassword));
				userService.save(user);
				return new VueResponse(true, "密码修改成功！");
			} else {
				return new VueResponse(false, "原密码不正确！");
			}
		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(false, "无法修改密码！");
		}
	}

	@ApiOperation(value = "用户修改信息")
	@PostMapping("/changeMessage")
	public VueResponse changeMessage(UserChangeDTO userChange, HttpSession session) {

		try {
			User userSession = (User) session.getAttribute("userSession");
			if (userSession == null) {
				return new VueResponse(false, "用户非法登录！");
			}
			User user = userService.findById(userSession.getId());
			user = UserChangeDTO.userChangeToE(user, userChange);
			userService.save(user);
			return new VueResponse(true, "修改信息成功！");
		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(false, "修改信息失败！");
		}
	}

	@PostMapping("addImg")
	public VueResponse save(@RequestParam("file") MultipartFile file, HttpSession session) {
		try {
			User user = new User();
			User userSession = (User) session.getAttribute("userSession");
			String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
			user = userService.findById(userSession.getId());
			// p1为路径，user.getName()为相片名字，fileType为类型
			String filename = UUID.randomUUID() + fileType;
			Path path = Paths.get(ProjectPath.getRootPath("static/img/user/") + filename);
			File filePath = new File(ProjectPath.getRootPath("static/img/user/"));
			System.out.println("文件的保存路径：" + path);
			if (!filePath.exists() && !filePath.isDirectory()) {
				System.out.println("目录不存在，创建目录:" + filePath);
				filePath.mkdir();
			}
			user.setImg("img/user/" + filename);// 保存到数据库的路径
			// 把获得的文件保存
			file.transferTo(path.toFile());
			userService.save(user);
			return new VueResponse(true, "上传头像成功");
		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(false, "添加失敗");
		}
	}

	@PostMapping("/deleteImg")
	public VueResponse deleteImg(HttpSession session) {
		try {
			User user = new User();
			User userSession = (User) session.getAttribute("userSession");
			user = userService.findById(userSession.getId());
			File oldFile = new File(ProjectPath.getRootPath("static/") + user.getImg());
			if (oldFile.exists() && !user.getImg().equals("img/user/user-default.png"))
				oldFile.delete();
			user.setImg(null);
			userService.save(user);
			return new VueResponse(true, "删除图片成功");
		} catch (Exception e) { // TODO: handle exception
			return new VueResponse(false, "删除图片失败！");
		}
	}

	@ApiOperation(value = "用户成为志愿者", notes = "管理员操作")
	@PostMapping("/beVolunteer")
	public VueResponse beVolunteer(@RequestParam("userId") Long userId) {
		try {
			User user = userService.findById(userId);
			user.setType(TypeEmun.VOLUNTEER);
			userService.save(user);
			return new VueResponse(true, "操作成功！");
		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(false, "操作失败！");

		}
	}

	@PostMapping("/beManager")
	public VueResponse beManager(@RequestParam("userId") Long userId) {
		try {
			User user = userService.findById(userId);
			if (user.getType().equals(TypeEmun.MANAGER)) {
				user.setType(TypeEmun.ORDINARY);
			} else {
				user.setType(TypeEmun.MANAGER);
			}
			userService.save(user);
			return new VueResponse(true, "操作成功！");
		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(false, "操作失败！");

		}
	}

	@ApiOperation(value = "是否禁用用户的切换", notes = "管理员操作")
	@PostMapping("/lock")
	public VueResponse lock(@RequestParam("userId") Long userId) {
		try {
			User user = userService.findById(userId);
			if (user.getLocked().equals(LockedEmun.NO)) {
				user.setLocked(LockedEmun.YES);
			} else {
				user.setLocked(LockedEmun.NO);
			}
			userService.save(user);
			return new VueResponse(true, "操作成功！");
		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(false, "操作失败！");

		}
	}

	@ApiOperation(value = "用户获取领养资格", notes = "管理员操作")
	@PostMapping("/deleteMore")
	public VueResponse deleteMore(@RequestParam("ids") Long[] ids) {
		try {
			for (Long id : ids) {
				userService.deleteById(id);
			}
			return new VueResponse(true, "删除成功！");
		} catch (Exception e) {
			// TODO: handle exception
			return new VueResponse(false, "操作失败！！");

		}
	}

	@GetMapping("/getSession")
	public void get(HttpSession session) {
		String name = (String) session.getAttribute("username");
		User user = (User) session.getAttribute("userSession");
		System.err.println(user.getName() + user.getId() + user.getType());
	}

}
